package org.apache.derby.shared.common.sanity;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Method;

/**
 * @author ex_chenzy59
 * @since 2025/3/13
 *
 */
public class AssertFailure extends RuntimeException{
    private String threadDump;
    public AssertFailure(String message, Throwable nestedError) {
        super(message, nestedError);
        threadDump = dumpThreads();
    }
    public AssertFailure(String message) {
        super(message);
        threadDump = dumpThreads();
    }
    private boolean supportsThreadDump() {
        try {
            // This checks that we are on a jvm >= 1.5 where we
            // can actually do threaddumps.
            Thread.class.getMethod("getAllStackTraces", new Class[] {});
            return true;
        } catch (NoSuchMethodException nsme) {
            // Ignore exception
        }
        return false;
    }
    private String dumpThreads() {
        if (!supportsThreadDump()) {
            return "(Skipping thread dump because it is not supported on JVM 1.4)";
        }
        // NOTE: No need to flush with the StringWriter/PrintWriter combination.
        StringWriter out = new StringWriter();
        PrintWriter p = new PrintWriter(out, true);
        // Load the class and method we need with reflection.
        final Method m;
        try {
            Class<?> c = Class.forName("org.apache.derby.shared.common.sanity.ThreadDump");
            m = c.getMethod("getStackDumpString");
        } catch (Exception e) {
            p.println("Failed to load class/method required to generate " +
                    "a thread dump:");
            e.printStackTrace(p);
            return out.toString();
        }
        //Try to get a thread dump and deal with various situations.
        try {
            String dump = (String) m.invoke(null, (Object[])null);
            //Print the dump to the message string. That went OK.
            p.print("---------------\nStack traces for all live threads:");
            p.println(STR."\n\{dump}");
            p.println("---------------");
        } catch (Exception pae) {
            p.println("\nAssertFailure tried to do a thread dump, but there was an error:");
            pae.printStackTrace(p);
        }
        return out.toString();
    }
}
